using System;
using System.Collections.Generic;

namespace SharpMud.LPC
{
    public class Array : LPC.Object, System.Collections.ICollection
	{
		private object							            _syncRoot;
		private System.Collections.Generic.List<Object>	_Contents;

		#region Constructors
		public Array()
			:this(new Object[] {})
		{
		}

		public Array(params Object[] contents)
		{
            _Contents = new System.Collections.Generic.List<Object>(contents);
		}
		#endregion

		public void Add(Object value)
		{
			_Contents.Add(value);
		}

		public void Remove(Object value)
		{
			_Contents.Remove(value);
		}

		public void RemoveAt(int index)
		{
			_Contents.RemoveAt(index);
		}

		public void AddRange(Object[] values)
		{
			_Contents.AddRange(values);
		}

		public Object this[int index]
		{
			get
			{
				return (Object)_Contents[index];
			}
			set
			{
				_Contents[index] = value;
			}
		}

        public static bool TryParse(char[] text, ref int index, out LPC.Object result)
        {
            throw new NotImplementedException();

            List<LPC.Object> elements = new List<Object>();

            if (text[index] != '(')
                return false;
            if (text.Length-(index+2)>0 && text[index + 1] != '{')
                return false;
            if ((text.Length - (index + 1)) < 4)
                throw new InvalidLpcFormatException();

            int i2 = index;
            i2 = i2 + 2;

            for (; i2 < text.Length; i2++)
            {
                while (Char.IsWhiteSpace(text[i2]) && i2 < text.Length)
                    i2++;
                if (text[i2] == ',')
                {   elements.Add((LPC.Object)null);     i2++;   }

                LPC.Object[] elementParseResults = LPC.Object.Parse(text, ref i2, 1);
                if (elementParseResults.Length >= 1)
                {
                    elements.AddRange(elementParseResults);

                    while (Char.IsWhiteSpace(text[i2]) && i2 < text.Length)
                        i2++;
                    if (text[i2] == ',')
                    {
                        continue;
                    }
                    else if (text[i2] == '}' && (text.Length - (i2 + 1)) > 0 && text[i2 + 1] == ')')
                    {
                        break;
                    }
                    else
                    {
                        throw new InvalidLpcFormatException();
                    }
                }    
            }

            result = new LPC.Array(elements.ToArray());
            index = i2+1;
            return true;
        }

        #region ICollection Members

        public virtual bool IsSynchronized
		{
			get
			{
				return false;
			}
		}

		public int Count
		{
			get
			{
				return _Contents.Count;
			}
		}

		public void CopyTo(System.Array array, int index)
		{
			lock(this._Contents)
			{
				long x = 0;
				foreach(Object lo in this._Contents)
				{
					array.SetValue(lo,(long)(x + (long)index));
					x++;
				}
			}
		}

		public object SyncRoot
		{
			get
			{
				if (this._syncRoot == null)
				{
					System.Threading.Interlocked.CompareExchange(ref this._syncRoot, new object(), (object) null);
				}
				return this._syncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		public System.Collections.IEnumerator GetEnumerator()
		{
			return new ArrayEnumerator(this);
		}

		#endregion

		public override string ToParsableString()
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			sb.Append("({");
			if(this.Count>0)
			{
				foreach(LPC.Object lo in this)
				{
					sb.Append(lo.ToParsableString());
					sb.Append(",");
				}
			}
			else
			{
				sb.Append(",");
			}
			sb.Append("})");
			return sb.ToString();
		}

		private class ArrayEnumerator : System.Collections.IEnumerator
		{
			private int			index;
			private Array	la;

			internal ArrayEnumerator(Array val)
			{
				la = val;
			}

			#region IEnumerator Members

			public void Reset()
			{
				index = -1;
			}

			public object Current
			{
				get
				{
					if(index<0 || index>=la.Count)
						throw new InvalidOperationException("The enumerator is positioned before the first element of the collection or after the last element.");

					return la._Contents[index];
				}
			}

			public bool MoveNext()
			{
				index++;
				if(index>=la.Count)
					return false;
				else
					return true;
			}

			#endregion
		}

        #region ICloneable Members
        protected override Object Clone()
        {
            Array la = new Array();
            foreach (Object lo in this)
            {
                la.Add((Object)(((ICloneable)lo).Clone()));
            }
            return la;
        }

        #endregion
    }
}
